package com.spring.mybatis.core;

import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;

import java.util.Set;

/**
 * Mapper 文件扫描工具实现，扩展 Spring 自带的扫描工具，使之能扫描 Mapper interface
 *
 * @author yangjian
 */
public class MybatisClassPathBeanDefinitionScanner extends ClassPathBeanDefinitionScanner {
	public MybatisClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry)
	{
		super(registry);
	}

	@Override
	protected Set<BeanDefinitionHolder> doScan(String... basePackages)
	{
		Set<BeanDefinitionHolder> beanDefinitionHolders = super.doScan(basePackages);
		// 扫描完成后，修改 BeanDefinition, 使用 FactoryBean 替换
		for (BeanDefinitionHolder holder : beanDefinitionHolders) {
			// 方法一： 使用 FactoryBean
			holder.getBeanDefinition().getConstructorArgumentValues().addGenericArgumentValue(holder.getBeanDefinition().getBeanClassName());
			holder.getBeanDefinition().setBeanClassName(MybatisMapperFactoryBean.class.getName());

			// 方法二： 使用 factoryMethod
//			holder.getBeanDefinition().getConstructorArgumentValues().addIndexedArgumentValue(0, holder.getBeanDefinition().getBeanClassName());
//			holder.getBeanDefinition().setBeanClassName(MybatisMapperFactoryMethod.class.getName());
//			holder.getBeanDefinition().setFactoryMethodName("getMapper");
		}
		return beanDefinitionHolders;
	}

	@Override
	protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition)
	{
		return beanDefinition.getMetadata().isInterface();
	}
}
